//global
var markerList = [];
var markerHash = {}
var strainPositions = {};
var hpccallList = [];
var strainListPlot=[];
var binWidth = 55;
var layout = "Physical";
var considerRange = false;
var offset = 100;
var allChrView = false;
var gchr = "chr01";
var dendJson = ycr5Json;
var qmarkersummarycoll="markersummary_1108";
var hapallelescoll="hapalleles_1108";
var progenysetcoll="progenyset";
var replot=false;
var progenySig={'RAP1_GCD7':"MLN_Beta1",'TEST':"TOR1",'GCN4':"GCN4","TETRAD1":"Tetrad1","TETRAD2":"Tetrad2"};

jQuery(function () {
	$( "#tabs" ).tabs();
	var chrval = $('#chromosome').val();
        jQuery('#markers').combobox(['ALL']);
    jQuery('#parentmarker').combobox([' ']);
	$('#chromosome').val("14");
        $('#markers').val("ALL");
    $('#parentchr').val("14");
	updateMarkerList("14", replot);

    updateParentMarkerList("14");
    $('#progenyform').hide();
    $('#parent_detail_div_YCR5').hide();

	jQuery('#signature_list').change(function(){
		updateProgenyList($('#signature_list').val());
	});

	setSignatureList("YCR6");
	jQuery('#chromosome').change(function(){
		var chrval = $('#chromosome').val();
		if (chrval == "ALL"){
			alert("Markers must be entered in form of chrN1:pos1 chrN2:pos2, and pos1 < pos2 if N2 != N1");
			$('#markers').val("");
			$('#marker_layout').val("Bin");			
			layout = "Bin";	
			return;
		}
		updateMarkerList(chrval, replot);
        });

    jQuery('#parentchr').change(function(){
		replot=false;
		var chrval = $('#parentchr').val();	
		updateParentMarkerList(chrval);
    });

	jQuery('#parentselect').change(function(){
		replot=false;
		retrieveProgeny();
	});

	jQuery('#parentmarker').change(function(){
		replot=false;
		retrieveProgeny();
	});

    	$('#tabs').bind('tabsselect', function(event, ui) {
	if (ui.index == 0){
		hapGo();
	}
	if (ui.index == 1){
                draw();
        }
   });
	jQuery('#markers').change(function(){
    		$('#markers').qtip({
        	content: 'Marker input field, ALL means all markers for selected chr. Enter start-end for a range of markers. For intra chromosome markers, use chr1:position chr2:postion2 ... Range and Intra chromosome markers are supported by the Bin Layout ',
        	show: 'mouseover',
        	hide: 'mouseout'
        	});
		if ($('#markers').val().indexOf('-') != -1){
			//alert("Marker range view is only supported in Bin layout view");
			$('#marker_layout').val("Bin");
			layout = "Bin";
			considerRange = true;
		}
		if ($('#markers').val().indexOf(' ') != -1){
			 $('#marker_layout').val("Bin");
                        layout = "Bin";
                        considerRange = true;
		}
		if ($('#markers').val() == 'ALL'){
			updateMarkerList($('#chromosome').val(), replot);
		}
		
	});

	
});

function retrieveProgeny(){
	chr=$('#parentchr').val();
        var marker=$('#parentmarker').val();
        var parent=$('#parentselect').val();
        var allele='1';
        if(parent == 'A'){
            allele = '2';
        }

            var spurl = "/cgi-bin/happyproxy?qcollection=" + hapallelescoll + "&qchr="+chr+"&qmarkers="+marker+"&qallele=" + allele;
            var _spcallback = function(resp){
                    var data = $.parseJSON(resp);
                    var results = data.results;
                    var strainList="";
                    for(var i=0; i< results.length; i++){
                        if(i==0){
                                strainList=results[i].strain;
                        }
                        else{
                                strainList=strainList + " "+results[i].strain;
                        }
                    }
                    $("#pp_list").val(strainList);
			replot=true;
            };

        $.get(spurl, "", _spcallback);
}

function setSignatureList(crossing){
	if(crossing == "YCR6"){
		$('<option value="RAP1_GCD7">MLN_Beta1</option><option value="TEST">TOR1</option>').appendTo('#signature_list');
		$('<option value="GCN4">GCN4</option><option value="TETRAD1">Tetrad1</option><option value="TETRAD2">Tetrad2</option>').appendTo('#signature_list');
		$('#signature_list').change();		
	}
	else{

		$('#signature_list').empty();
		$('#progeny_list').val("");
	}


}

function resetHDivs(){
	$("#hapmarkers").html("");
        $("#hapcalls").html("");
        $("#gbrowse-input").html("");
}
function hapGo(){
    var strainList="";
    if($("#progenyrb").attr('checked')){
	strainList = $("#progeny_list").val();
	
     }
    else{
	strainList= $("#pp_list").val();
    }

    if ($("#chromosome").val() == "ALL"){
	    allChrView = true;
     }

     chr=$('#chromosome').val();

     if(strainList == ""){
	return;
	}

     resetHDivs();
     retrieveHCall(strainList);
	//consider layout view when determining gbrowse end
     appendGbrowse(50,200, Math.floor(chrlenhash[chr]/1000));
        
}

function appendGbrowse(start, end, chrlength){
	var width = chrlength;
	$( "#gbrange1" ).val(start);
	$("#slider-range").attr("style", "width:"+width+"px");
	$( "#slider-range" ).slider({
                        range: true,
                        min: 0,
                        max: chrlength,
                        values: [ start, end],
                        slide: function( event, ui ) {
                                $( "#gbrange1" ).val( (ui.values[0]*1000) + ".." + (ui.values[1]*1000) );
                        }
                });
	$("#gbrowse-input").append('<b>Chr</b>:' + $("#chromosome").val() + '&nbsp;<b>Range(Kilobase)</b>&nbsp;<input id="gbrange1" type="text" size="20" value="">&nbsp;Gene&nbsp;<input id="gbgene" type="text" size="12" value=""> ');
	$("#gbrowse-input").append("&nbsp;&nbsp;<button class='button' id='gbrowse_button' onclick='JavaScript:launchGBrowse()'>GBrowse</button>");	
}

function launchGBrowse(){
	var chr = $("#chromosome").val();
	var prefix = "chr";
	if (chr.length < 2)
		chr = "0" + chr;
	if ($('#chromosome').val() == 'ALL'){
		chr = gchr;
		prefix = "";
	}
	var range = $("#gbrange1").val();
	var gurl = "http://gbrowse.systemsbiology.net/cgi-bin/gb2/gbrowse/yeast/?name=" + prefix + chr + ":" + range;
	var gene = $("#gbgene").val();
	if (gene != null && gene.length > 1)
		gurl = "http://gbrowse.systemsbiology.net/cgi-bin/gb2/gbrowse/yeast/?name=" + gene;
	window.open(gurl, "GBrowse", "height=600, width=880");	
}

function retrieveHCall(strainList){
	$.blockUI({ 
            message: '<h1>Loading and drawing haplotype map...</h1>'
        }); 

	var strains = strainList.split(" ");
	var strainNum = strains.length;
	for (var si = 0; si < strainNum; si++){
		strainPositions[strains[si]] = si; 
	}
	var chr= $("#chromosome").val();
	var markerNum = markerList.length;
	hpccallList = new Array(markerNum);
	var rhcurl = "/cgi-bin/happyproxy?qcollection=" + hapallelescoll + "&qstrains=" + strainList + "&qchr=" + chr;
	var inputMarker = $("#markers").val();
	if (inputMarker != null && inputMarker != "ALL")
		rhcurl = rhcurl + "&qmarkers=" + inputMarker; 
        var markerCalls = null;
	var currentStrain = "";
	var _rhccallback = function(resp){
                var data = $.parseJSON(resp);
                var results = data.results;
		strainListPlot=new Array(strainNum);
		for (var hi = 0; hi < results.length; hi++){
			var hcobj = results[hi];
			var markerIter = hi % strainNum;
			if (markerIter == 0){
				markerCalls = new Array(strainNum);
			}
			var pos = strainPositions[hcobj["strain"]];
			strainListPlot[pos] = hcobj["strain"] + "," + hcobj["plate"] + "," + hcobj["tetrad"];
			markerCalls[pos] = hcobj["allele"];
			if (markerIter == (strainNum - 1)){
				hpccallList[Math.floor(hi/strainNum)] = markerCalls;            
                	}
		}
		plotHap();
		$.unblockUI();
        };
        $.get(rhcurl, "", _rhccallback);
}

function plotHap(){
    	var strains = strainListPlot; 
	var lowreads = new Array(strains.length);
	for (var si = 0; si < strains.length; si++){
                lowreads[si] = 0;
        }
	if ($("#chromosome").val() != "ALL"){
		$('#hapmarkers').html("Chr:" + $("#chromosome").val() + " " + markerList.length + " Markers(kb scale)");
	}else{
		$('#hapmarkers').html("Intrachromosomal bin view");
	}
	$("#tabmarkers").html("chr:" + $("#chromosome").val() + " Markers<br><br>");
	var chart = d3.select("#hapcalls")
   .append("svg:svg")
     .attr("class", "chart")
     .attr("height", (20 * strains.length) + 80);
	var g = chart.append("svg:g")
	.attr("transform", "translate(0,0)");
        var markers = $("#markers").val();
	var chr = $("#chromosome").val();
	if (markers != "ALL" && (markers.indexOf("-") != -1 || markers.indexOf(" ") != -1) && chr != "ALL"){
		//go thru markers list and create new sublist
		var newMarkerList = [];
		var lowerBound = markers.split("-")[0];
		var upperBound = markers.split("-")[1];
		for (var nl=0; nl < markerList.length; nl++){
			if (markerList[nl] >= lowerBound && markerList[nl] <= upperBound) 
				newMarkerList.push(markerList[nl]);
		}
		markerList = newMarkerList;
	} 	
	if (chr == "ALL"){
		var newMarkerList = [];
		markerHash = {}; 
		var mList = markers.split(" ");
		for (var nl=0; nl < mList.length; nl++){
			var markerStr = mList[nl].split(":");
			newMarkerList.push(markerStr[1]);
			markerHash[markerStr[1]] = markerStr[0] + ":" + Math.floor(parseInt(markerStr[1])/1000);
		}
		newMarkerList.sort(sortNumber);
		markerList = newMarkerList;
	}
	if (chr != "ALL" && markers.indexOf(" ") != -1){
		var newMarkerList = [];
                markerHash = {};
                var mList = markers.split(" ");
                for (var nl=0; nl < mList.length; nl++){
                        newMarkerList.push(Math.floor(parseInt(mList[nl])));
                }
                newMarkerList.sort(sortNumber);
                markerList = newMarkerList;
	}

	for (var di = 0; di < markerList.length; di++){
		var ml = markerList[di];
		/*if (ml > 674000 && ml < 690000 ){
			alert(ml);	
		}*/
		var prevdata = null;
		if (di > 0){
			prevdata = hpccallList[di-1];
		}
		var nextdata = null;
		if (di != markerList.length -1 ){
                        nextdata = hpccallList[di+1];
                }
		var rdata = hpccallList[di];
		if (rdata == null){
			rdata = lowreads;
		}
		g.selectAll("rect"+di)
     	.data(rdata)   
     .enter().append("svg:rect")
     .attr("x", function(d, i){
	if (layout == "Bin"){
		return binWidth*(di+1) + offset;
	}else{
		if (Math.floor(markerList[di]/1000)*5 < 50 || considerRange)
			offset = 100
		var dx = Math.floor(markerList[di]/1000)*5 + offset;
		if (considerRange)
			dx= dx - Math.floor(markerList[0]/1000)*5 + offset;
		return dx;//Math.floor(markerList[di]/1000)*5 + offset;
	}
	})
     .attr("y", function(d, i) { 
	return i*20 + 50; 
	})
     .attr("width", function(d,i){
	//width depends on physical map versus marker abstract view 
	if (layout == "Bin"){
		return binWidth;
	}else{
		var markerEnd = 0;
		if (di == markerList.length - 1){
			markerEnd = markerList[di] + binWidth;
		}else{
			markerEnd = markerList[di+1];
		}		
		return Math.floor((markerEnd - markerList[di]))/1000 + binWidth*5;
	}		
	})
     .attr("height", 20)
     .style("fill", function(d, i){
			var gradid = "redgradient";
			var gcolor = d3.rgb("#E41B17");
			var gcolorend = gcolor;//d3.rgb("red");//red.brighter(5);//"lightpink1";
			if (d == 1 ) {
				if (prevdata != null && prevdata[i] == 2){
                                        gradid = "code12gradient";
                                        gcolor = d3.rgb("purple");
                                        gcolorend = d3.rgb("purple");
                                }
				if (prevdata != null && prevdata[i] == 22){
                                        gradid = "code121gradient";
                                        gcolor = d3.rgb("#9E7BFF");
                                        gcolorend = d3.rgb("#9E7BFF");
                                }
			}
			if (d == 11){
                                gradid = "code11gradient";
				gcolor = d3.rgb("red");
				gcolorend = gcolor; //d3.rgb("#F75D59");//indian red
				if (prevdata != null && (prevdata[i] == 2 || prevdata[i] == 22)){
                                        gradid = "code121gradient";
                                        gcolor = d3.rgb("#9E7BFF");
                                        gcolorend = d3.rgb("#9E7BFF");
                                }
                        }
			if (d == 2){
				gradid = "code2gradient";
				gcolor = d3.rgb("#2B60DE");
                                gcolorend = gcolor;
				if (prevdata != null && prevdata[i] == 1){
					gradid = "code12gradient";
	                                gcolor = d3.rgb("purple");
        	                        gcolorend = d3.rgb("purple");
				}
				if (prevdata != null && (prevdata[i] == 11)){
                                        gradid = "code121gradient";
                                        gcolor = d3.rgb("#9E7BFF");
                                        gcolorend = d3.rgb("#9E7BFF");
                                }
			}
			if (d == 22){
                                gradid = "code22gradient";
                                gcolor = d3.rgb("#306EFF");
				gcolorend = gcolor; //d3.rgb("#6698FF");//skyblue
				if (prevdata != null && (prevdata[i] == 1 || prevdata[i] == 11)){
                                        gradid = "code121gradient";
                                        gcolor = d3.rgb("#9E7BFF");
                                        gcolorend = d3.rgb("#9E7BFF");
                                }
                        }	
			if (d == 0 || d == null){
				//low reads
				gradid = "greygradient";
				gcolor = d3.rgb("grey");
	                        gcolorend = d3.rgb("grey");
				if (prevdata != null && nextdata != null){
					var pd = prevdata[i];
					var nd = nextdata[i];
					if ((pd == 1 || pd == 11) && (nd == 2 || nd == 22)){
						gradid = "code121gradient";
                                        	gcolor = d3.rgb("#9E7BFF");
                                        	gcolorend = d3.rgb("#9E7BFF");
					}
					if ((pd == 2 || pd == 22) && (nd == 1 || nd == 11)){
                                                gradid = "code121gradient";
                                                gcolor = d3.rgb("#9E7BFF");
                                                gcolorend = d3.rgb("#9E7BFF");
                                        }
				}				
			}
			if (d == 3){
				//ambiguous
                                gradid = "greengradient";
                                gcolor = d3.rgb("green");
                                gcolorend = d3.rgb("green"); 
			}
			var gradient = g.append("svg:defs")
                                  .append("svg:linearGradient")
                                .attr("id", gradid)
                                .attr("x1", "100%")
                                .attr("y1", "100%")
                                .attr("x2", "0%")
                                .attr("y2", "0%")
                                .attr("spreadMethod", "pad");
                                gradient.append("svg:stop")
                                    .attr("offset", "0%")
                                    .attr("stop-color", gcolorend)
                                    .attr("stop-opacity", 1);
                                gradient.append("svg:stop")
                                    .attr("offset", "100%")
                                    .attr("stop-color", gcolor)
                                    .attr("stop-opacity", 1);
			return "url(#" + gradid + ")";
		});
	}
	var x = d3.scale.linear()
        .domain([0, chrlenhash[$('#chromosome').val()]])
        .range([0, 7000]);	
	var xt10 = x.ticks(100);
	
	g.selectAll("_myline")
     .data(markerList)
   .enter().append("svg:line")
     .attr("x1", function(d, i){
                if (layout == "Bin"){
                        return (i)*(binWidth) + binWidth + offset;
                }else{
			var dx= Math.floor(d/1000)*5 + offset;
                	if (considerRange)
                        	dx= dx - Math.floor(markerList[0]/1000)*5 + offset;
                	return dx;//Math.floor(markerList[di]/1000)*5 + offset;

                }
	})
     .attr("x2", function(d, i){
                if (layout == "Bin"){
                        return (i)*(binWidth) + binWidth + offset;
                }else{
                        var dx= Math.floor(d/1000)*5 + offset;
                if (considerRange)
                        dx= dx - Math.floor(markerList[0]/1000)*5 + offset;
                return dx;//Math.floor(markerList[di]/1000)*5 + offset;

                }
	})
     .attr("y1", 32)
     .attr("y2", 40)
      .attr("stroke-width", 3)
     .attr("stroke", "#ccc")
     .attr("title", function(d, i){return "name_" + i;})
     .attr("name", function(d, i){return "name_" + i;})
     .attr("id", function(d, i){return "mktickid_" + i;})
     .on("mouseover", function(d, i) {
	$('#mktickid_' + i).qtip({
   	content: 'marker:' + d,
   	show: 'mouseover',
   	hide: 'mouseout'
	});	
	})
	.on("click", function(d, i) {
       		if ($('#chromosome').val() != 'ALL'){
			$( "#gbrange1" ).val(d + ".." + (markerList[i+1]));
		}else{
			gchr = markerHash[d].split(":")[0];
			$( "#gbrange1" ).val(d + ".." + (parseInt(d)+2000));
		}
        });

	g.selectAll("text.rule")
     .data(markerList)
     .enter().append("svg:text")
     .attr("class", "rule")
     .attr("x", 0)
     .attr("y", 30)
     .attr("dx", 
	function(d, i){
		if (layout == "Bin"){
			return (i)*(binWidth) + binWidth + offset;
		}else{
			var dx = Math.floor(d/1000)*5 + offset;
                if (considerRange)
                        dx= dx - Math.floor(markerList[0]/1000)*5 + offset;
                return dx;//Math.floor(markerList[di]/1000)*5 + offset;

		}
	}
	)
     .attr("text-anchor", "middle")
     .text(function(d,i){
		var mlabel = Math.floor(d/1000);
		if ((i == 0 || layout == "Bin") && chr != "ALL")
			return mlabel
		if (i%5 == 0 && chr != "ALL")        
                	return mlabel;
		if (chr == "ALL")
			return markerHash[d];
		return "";
	});
	g.selectAll(".yLabel")
	.data(strains)
      .enter().append("svg:text")
     .attr("class", "yLabel")
     .attr("x", 0)
     .attr("y", function(d, i) { 
	return i*20 + 65;
	})
     .attr("text-anchor", "right")
     .text(function(d, i){return strains[i];});
}

//draw dendrogram
function prepDraw(){
	var signatureName = "";
	var progenyList=[];
	if($('#progenyrb').attr('checked')){
	 signatureName = $('#signature_list').val();
         progenyList = $('#progeny_list').val().split(" ");
	}
	else{
		signatureName= $('parentselect').val();
		progenyList = $('#pp_list').val().split(" ");
	}
	
        var pChildren = [];
        for (var pi = 0; pi < progenyList.length; pi++){
        	var ph = {};
                ph["name"] = progenyList[pi];
                ph["size"] = 2000;
                pChildren.push(ph);
         }
         $("#tabs-3").html("");
         var signatureSet = [
         {
         	"name": signatureName,
                "children": pChildren
         }
         ];
         dendJson["children"] = signatureSet;
}

function draw(){
	prepDraw();
	var w = 960,
	h = 360;//2000;
	var tree = d3.layout.tree()
	.size([h, w - 160])
	.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });

	var diagonal = d3.svg.diagonal()
    	.projection(function(d) { return [d.y, d.x]; });
	
	var vis = d3.select("#tabs-3").append("svg:svg")
    	.attr("width", w*2)//w)
    	.attr("height", w*2-150)//h)
  	.append("svg:g")
    	.attr("transform", "translate(10, 0)");
   	var nodes = tree.nodes(dendJson);
   	var link = vis.selectAll("path.link")
      	.data(tree.links(nodes))
    	.enter().append("svg:path")
      	.attr("class", "link")
      	.attr("d", diagonal);
	
        var node = vis.selectAll("g.node")
        .data(nodes)
        .enter().append("svg:g")
        .attr("class", "node")
        .attr("transform", function(d) { 
		return "translate(" + d.y + "," + d.x + ")"; 
	})
  	node.append("svg:circle")
        .attr("r", 4.5);
  	node.append("svg:text")
        .attr("dx", function(d) { 
		return d.children ? 40 : 10; 
	})
      	.attr("dy", function(d) { 
		return d.children ? 15 : 3}
	)
      	.attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
      	.text(function(d) { return d.name; });
}

function updateMarkerList(chr, replot){
	var mlurl = "/cgi-bin/happyproxy?qchr=chr" + chr + "&qcollection=" + qmarkersummarycoll;
        var _mlcallback = function(resp){
                var data = $.parseJSON(resp);
                var listresults = data.results;
		markerList = [];
		for (var li in listresults){
			markerList.push(listresults[li].position);
		}
        	jQuery.combobox.instances[0].setSelectOptions(markerList);
                $('#markers').val("ALL");
		if (replot){
            hapGo();
		}
	};
        $.get(mlurl, "", _mlcallback);
}

function updateParentMarkerList(chr){
	var mlurl = "/cgi-bin/happyproxy?qchr=chr" + chr + "&qcollection=" + qmarkersummarycoll;
        var _mlcallback = function(resp){
                var data = $.parseJSON(resp);
                var listresults = data.results;
		parentmarkerList = [];
		for (var li in listresults){
			parentmarkerList.push(listresults[li].position);
		}
        	jQuery.combobox.instances[1].setSelectOptions(parentmarkerList);
                $('#parentmarker').val(parentmarkerList[0]);
		$('#parentmarker').change();

	};
        $.get(mlurl, "", _mlcallback);
}

function updateProgenyList(signature){
	var signature = $("#signature_list").val();
	var spurl = "/cgi-bin/happyproxy?qsignature=" + signature + "&qcollection=" + progenysetcoll;
	var _spcallback = function(resp){
		var data = $.parseJSON(resp);
		var results = data.results[0];
		$("#progeny_list").val(results.ylist);
		draw();
	}; 
	$.get(spurl, "", _spcallback);
}

function updateLayout(mlayout){
	if (mlayout == "Physical" && $("#chromosome").val() == "ALL"){
		alert("Layout can not be Physical for ALL chromosomes or marker lists inputs");
		return;
	}
	layout = mlayout;
	hapGo();
}

function updateSearchForm(){
    var parentrbValue = $("#parentrb").attr('checked');
    if(parentrbValue){
        $("#progenyform").hide();
        $("#parentform").show();
    }
    else{
        $("#progenyform").show();
        $("#parentform").hide();
    }

}

function updateCross(crossing){

        if(crossing=="YCR6"){
                $('#parent_detail_div_YCR6').show();
                $('#parent_detail_div_YCR5').hide();
                qmarkersummarycoll="markersummary_1108";
                hapallelescoll="hapalleles_1108";
                progenysetcoll="progenyset";
        }
        else{
                $('#parent_detail_div_YCR5').show();
                $('#parent_detail_div_YCR6').hide();
                qmarkersummarycoll="markersummary_0530";
                hapallelescoll="hapalleles_0530";
                progenysetcoll="";
        }

	$('#parentchr').change();
	$('#chromosome').change();
	setSignatureList(crossing);
	

}
function exportData(){
var strains="";
    if($("#progenyrb").attr('checked')){
        strains = $("#progeny_list").val();

     }
    else{
        strains= $("#pp_list").val();
    }

	var chr= $("#chromosome").val();
	$('#frame').attr('src',"http://" + window.location.host + "/cgi-bin/happyproxy/hapalleles.csv?qcollection=" + hapallelescoll + "&qstrains=" + strains + "&qchr=" + chr + "&export=true");

}

function sortNumber(a,b)
{
return a - b;
}
